﻿#pragma once

#include "TimeSys.h"

namespace ns_Time
{
    class UnixTime : public TimeSys
    {
    public:
        using ClockType = long long;
        using MillisecondType = double;

    public:
        UnixTime()
        {
        }

        UnixTime(ClockType clock, MillisecondType millisecond)
            : _clock(clock),
              _millisecond(millisecond)
        {
        }

        SecondCount SecondFromRefTime() const override
        {
            UnixTime *RefTime = GetRefTime();
            return static_cast<SecondCount>(_clock - RefTime->_clock + _millisecond);
        }

        UnixTime *TimeAfterSecond(SecondCount seconds) const override
        {
            int secondsInt;
            double secondsMilli;
            Mathf::SplitDouble(seconds, &secondsInt, &secondsMilli);
            UnixTime *ans = new UnixTime(_clock + secondsInt, _millisecond + secondsMilli);
            return ans;
        }

        UnixTime *GetRefTime() const override
        {
            static UnixTime RefTime = UnixTime(315504000, 0);
            return &RefTime;
        }

        bool Decode(const std::string& inJson) override
        {
            Json::Value inValue;
			Json::Reader reader;
			bool parsingSuccessful = reader.parse(inJson, inValue);
			if (!(parsingSuccessful && inValue["Type"].asString() == "TimeSys"))
				return false;

            SecondCount seconds = inValue["SecondsFromRefTime"].asDouble();

            auto tmp = GetRefTime()->TimeAfterSecond(seconds);
            *this = *tmp;

            return true;
        }

    private:
        ClockType _clock;
        MillisecondType _millisecond;
    };
}